﻿open System
open System.IO
open System.Xml.Linq
open Zipper.Applications.BinaryTree
open Zipper.Demo.Pangolin

let private makeName n = XName.op_Implicit(n)
let private nodeName = makeName "Node"
let private answerName = makeName "answer"
let private questionName = makeName "question"

let rec private toXml (t:tree<string,string>) =
    match t with
        | Leaf s -> new XElement(nodeName, new XAttribute(answerName, s))
        | Node (q,l,r) -> new XElement(nodeName,
                            new XAttribute(questionName, q),
                            toXml l,
                            toXml r)

let rec private fromXml (e:XElement) =
    let q = e.Attribute(questionName)
    if q = null then Leaf (e.Attribute(answerName).Value)
                else let lr = e.Elements(nodeName) |> Seq.take 2 |> Array.ofSeq
                     let l = fromXml lr.[0]
                     let r = fromXml lr.[1]
                     Node (q.Value, l, r)

let private yesNo q =
    printf "%s (y/n) " q
    let key = Console.ReadKey().Key
    printfn ""
    key = ConsoleKey.Y

let private ask q =
    printf "%s " q
    Console.ReadLine()

let private newline () = printfn ""

let private fileName = "pangolin.xml"
let private defaultTree = Leaf "Elephant"

let tree = if File.Exists(fileName) then XElement.Load(fileName) |> fromXml else defaultTree
tree |> pangolin yesNo ask newline |> toXml |> fun x -> x.Save(fileName)